home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / pmlpp140.zip / SRC / pmlpp.c < prev    next >
C/C++ Source or Header  |  1997-08-14  |  18KB  |  629 lines

  1. /*
  2. PMLPP - A POP3 mail "peeker" for OS/2<tm>.
  3. Copyright (C) 1997 James R. Louvau
  4.  
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. You may contact the author of PMLPP at:
  20.  
  21. E-mail     : jim@vwm.com
  22. Snail-mail : Jim Louvau
  23.              3437 335th St.
  24.              West Des Moines, IA 50266
  25. */
  26.  
  27. #include "pmlpp.h"
  28.  
  29. #define MAXERRORMSGS 8
  30. static PSZ ErrorMsgs[ MAXERRORMSGS ] = 
  31. {
  32.    "ADDR",  /* -1 */
  33.    "SOCK",  /* -2 */
  34.    "CONN",  /* -3 */
  35.    "SRVR",  /* -4 */
  36.    "USER",  /* -5 */
  37.    "PASS",  /* -6 */
  38.    "STAT",  /* -7 */
  39.    "VALU",  /* -8 */
  40. };
  41.  
  42. static void
  43. CenterWindow( HWND hwnd )
  44. /***********************/
  45. {
  46.    SWP swp;
  47.  
  48.    WinQueryWindowPos( hwnd, &swp );
  49.  
  50.    swp.x = ( WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ) - swp.cx ) / 2;
  51.    swp.y = ( WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) - swp.cy ) / 2;
  52.  
  53.    WinSetWindowPos( hwnd, HWND_TOP, swp.x, swp.y, 0, 0, SWP_SHOW | SWP_MOVE | SWP_ZORDER );
  54. }
  55.  
  56. static HWND
  57. LoadHelp( HWND hwndFrame )
  58. /************************/
  59. {
  60.    PPIB     ppib;
  61.    PTIB     ptib;
  62.    HELPINIT hi;
  63.    PSZ      pszExt;
  64.    CHAR     szName[ CCHMAXPATH ];
  65.    HWND     hwndHelp;
  66.  
  67.    DosGetInfoBlocks( &ptib, &ppib );
  68.  
  69.    DosQueryModuleName( ppib->pib_hmte, sizeof( szName ), szName );
  70.  
  71.    pszExt = strrchr( szName, '.' );
  72.    if ( pszExt )
  73.    {
  74.       strcpy( pszExt, ".hlp" );
  75.    }
  76.    else
  77.    {
  78.       strcat( szName, ".hlp" );
  79.    }
  80.  
  81.    hi.cb                       = sizeof( HELPINIT );
  82.    hi.ulReturnCode             = 0;
  83.    hi.pszTutorialName          = NULL;
  84.    hi.phtHelpTable             = ( PHELPTABLE ) MAKELONG( DLG_PMLPP, 0xffff );
  85.    hi.hmodHelpTableModule      = NULLHANDLE;
  86.    hi.hmodAccelActionBarModule = NULLHANDLE;
  87.    hi.idAccelTable             = 0;
  88.    hi.idActionBar              = 0;
  89.    hi.pszHelpWindowTitle       = "Help for PMLPP";
  90.    hi.fShowPanelId             = CMIC_HIDE_PANEL_ID;
  91.    hi.pszHelpLibraryName       = szName;
  92.  
  93.    hwndHelp = WinCreateHelpInstance( WinQueryAnchorBlock( hwndFrame ), &hi );
  94.    if ( hwndHelp != NULLHANDLE )
  95.    {
  96.       WinAssociateHelpInstance( hwndHelp, hwndFrame );
  97.       return ( hwndHelp );
  98.    }
  99.    else
  100.    {
  101.       return ( NULLHANDLE );
  102.    }
  103. }
  104.  
  105. static HWND
  106. LoadMenu( HWND hwnd )
  107. /*******************/
  108. {
  109.    MENUITEM mi;
  110.    HWND     hmenu = WinLoadMenu( HWND_OBJECT, NULLHANDLE, MNU_CONTEXT );
  111.    if ( hmenu != NULLHANDLE )
  112.    {
  113.       WinSendMsg( hmenu, MM_QUERYITEM, MPFROM2SHORT( IDM_HELP, TRUE ),
  114.                   MPFROMP( &mi ));
  115.  
  116.       WinSetWindowBits( mi.hwndSubMenu, QWL_STYLE, MS_CONDITIONALCASCADE,
  117.                         MS_CONDITIONALCASCADE );
  118.  
  119.       WinSendMsg( mi.hwndSubMenu, MM_SETDEFAULTITEMID,
  120.                   MPFROMSHORT( IDM_GENERALHELP ), MPVOID );
  121.    }
  122.  
  123.    return ( hmenu );
  124. }
  125.  
  126. static void
  127. SetButtonIcon( HWND     hwndButton,
  128.                HPOINTER hicon      )
  129. /**********************************/
  130. {
  131.    WNDPARAMS wp;
  132.    BTNCDATA  bd;
  133.  
  134.    wp.fsStatus  = WPM_CTLDATA;
  135.    wp.cbCtlData = sizeof( BTNCDATA );
  136.    wp.pCtlData  = &bd;
  137.  
  138.    WinSendMsg( hwndButton, WM_QUERYWINDOWPARAMS, MPFROMP( &wp ), MPVOID );
  139.    bd.hImage = hicon;
  140.    WinSendMsg( hwndButton, WM_SETWINDOWPARAMS, MPFROMP( &wp ), MPVOID );
  141. }
  142.  
  143. static HWND
  144. LaunchMailreader( HWND    hwnd,
  145.                   PCONFIG pcfg )
  146. /******************************/
  147. {
  148.    PROGDETAILS   pd = { 0 };
  149.  
  150.    pd.Length                        = sizeof( pd );
  151.    pd.progt.progc                   = PROG_DEFAULT;
  152.    pd.pszExecutable                 = pcfg->szProgram;
  153.    pd.pszStartupDir                 = pcfg->szDirectory;
  154.    pd.pszParameters                 = pcfg->szOptions;
  155.    pd.swpInitial.hwndInsertBehind   = HWND_TOP;
  156.    pd.swpInitial.fl                 = SWP_ACTIVATE | SWP_SHOW;
  157.    pd.swpInitial.hwnd               = hwnd;
  158.  
  159.    return ( WinStartApp( hwnd, &pd, NULL, NULL, SAF_INSTALLEDCMDLINE ));
  160. }
  161.  
  162. MRESULT EXPENTRY
  163. TransparentWndProc( HWND   hwnd,
  164.                     ULONG  msg,
  165.                     MPARAM mp1,
  166.                     MPARAM mp2  )
  167. /*******************************/
  168. {
  169.    PFNWP pfnOrgWndProc = ( PFNWP ) WinQueryWindowPtr( hwnd, 0 );
  170.  
  171.    switch ( msg )
  172.    {
  173.       case WM_CONTEXTMENU:
  174.       case WM_BUTTON1MOTIONSTART:
  175.       case WM_BUTTON2MOTIONSTART:
  176.       case WM_BUTTON1DBLCLK:
  177.       case WM_BUTTON2DBLCLK:
  178.          {
  179.             WinSendMsg( WinQueryWindow( hwnd, QW_OWNER ), msg, mp1, mp2 );
  180.          }
  181.          return ( MRTRUE );
  182.  
  183.       case WM_PAINT:
  184.          {
  185.             if ( WinQueryWindowUShort( hwnd, QWS_ID ) == ST_STATUS )
  186.             {
  187.                RECTL rcl;
  188.                HPS   hps;
  189.  
  190.                pfnOrgWndProc( hwnd, msg, mp1, mp2 );
  191.  
  192.                WinQueryWindowRect( hwnd, &rcl );
  193.  
  194.                hps = WinGetPS( hwnd );
  195.  
  196.                WinDrawBorder( hps, &rcl, 1, 1, 0, 0, DB_AREAATTRS | 0x0800 );
  197.  
  198.                WinReleasePS( hps );
  199.  
  200.                return ( MRTRUE );
  201.             }
  202.          }
  203.          break;
  204.    }
  205.  
  206.    return ( pfnOrgWndProc( hwnd, msg, mp1, mp2 ));
  207. }
  208.  
  209. MRESULT EXPENTRY
  210. PasswordDlgProc( HWND   hwnd,
  211.                  ULONG  msg,
  212.                  MPARAM mp1,
  213.                  MPARAM mp2  )
  214. /****************************/
  215. {
  216.    static PCONFIG pcfg = NULL;
  217.  
  218.    switch ( msg )
  219.    {
  220.       case WM_INITDLG :
  221.          {
  222.             pcfg = ( PCONFIG ) PVOIDFROMMP( mp2 );
  223.          }
  224.          return ( MRFALSE );
  225.  
  226.       case WM_COMMAND:
  227.          {
  228.             if ( SHORT1FROMMP( mp1 ) == DID_OK )
  229.             {
  230.                WinQueryDlgItemText( hwnd, EF_PASSWORD, sizeof( pcfg->szPassword ), pcfg->szPassword );
  231.                WinDismissDlg( hwnd, 1 );
  232.             }
  233.          }
  234.          return ( MRZERO );
  235.  
  236.       case WM_HELP:
  237.          {
  238.             HWND hwndHelp;
  239.  
  240.             hwndHelp = WinQueryHelpInstance( hwnd );
  241.             if ( hwndHelp != NULLHANDLE )
  242.             {
  243.                WinSendMsg( hwndHelp, HM_DISPLAY_HELP, MPFROMSHORT( EF_PASSWORD ), MPFROMSHORT( HM_RESOURCEID ));
  244.             }
  245.          }
  246.          return ( MRZERO );
  247.    }
  248.  
  249.    return ( WinDefDlgProc( hwnd, msg, mp1, mp2 ));
  250. }
  251.  
  252. MRESULT EXPENTRY
  253. PMLPPDlgProc( HWND   hwnd,
  254.               ULONG  msg,
  255.               MPARAM mp1,
  256.               MPARAM mp2  )
  257. /*************************/
  258. {
  259.    static HPOINTER hiconMain   = NULLHANDLE;
  260.    static HPOINTER hiconMail   = NULLHANDLE;
  261.    static HWND     hwndStatus  = NULLHANDLE;
  262.    static HWND     hwndButton  = NULLHANDLE;
  263.    static HWND     hwndHelp    = NULLHANDLE;
  264.    static HWND     hmenu       = NULLHANDLE;
  265.    static PCONFIG  pcfg        = NULL;
  266.    static LONG     cbOldMsgs   = ( -666 );
  267.    static BOOL     bForced     = FALSE;
  268.  
  269.    switch ( msg )
  270.    {
  271.       case WM_INITDLG :
  272.          {
  273.             pcfg = ( PCONFIG ) PVOIDFROMMP( mp2 );
  274.  
  275.             pcfg->hwndNotify = hwnd;
  276.  
  277.             hiconMain = WinLoadPointer( HWND_DESKTOP, NULLHANDLE, DLG_PMLPP );
  278.             hiconMail = WinLoadPointer( HWND_DESKTOP, NULLHANDLE, ICO_MAIL );
  279.             WinSendMsg( hwnd, WM_SETICON, MPFROMLONG( hiconMain ), MPVOID );
  280.  
  281.             hwndStatus = WinWindowFromID( hwnd, ST_STATUS );
  282.  
  283.             WinSetWindowPtr( hwndStatus, 0,
  284.                              WinSubclassWindow( hwndStatus, TransparentWndProc ));
  285.  
  286.             hwndButton = WinWindowFromID( hwnd, PB_REFRESH );
  287.  
  288.             WinSetWindowPtr( hwndButton, 0,
  289.                              WinSubclassWindow( hwndButton, TransparentWndProc ));
  290.  
  291.             hmenu = LoadMenu( hwnd );
  292.  
  293.             hwndHelp = LoadHelp( hwnd );
  294.  
  295.             if ( LoadProfile( hwnd, pcfg ))
  296.             {
  297.                WinSetWindowPos( hwnd, HWND_TOP, pcfg->ptl.x, pcfg->ptl.y, 0, 0,
  298.                                 SWP_MOVE | SWP_SHOW | SWP_ZORDER );
  299.  
  300.                if ( ! *( pcfg->szPassword ))
  301.                {
  302.                   WinDlgBox( HWND_DESKTOP, hwnd, PasswordDlgProc, NULLHANDLE, DLG_PASSWORD, pcfg );
  303.                }
  304.  
  305.                StartPolling( pcfg );
  306.             }
  307.             else
  308.             {
  309.                CenterWindow( hwnd );
  310.                WinPostMsg( hwnd, WM_COMMAND, MPFROMSHORT( IDM_PROPERTIES ),
  311.                            MPFROM2SHORT( CMDSRC_OTHER, FALSE ));
  312.             }
  313.          }
  314.          return ( MRFALSE );
  315.  
  316.       case WM_FORMATFRAME:
  317.          {
  318.             int   n;
  319.             PSWP  pswp   = ( PSWP ) PVOIDFROMMP( mp1 );
  320.             SHORT cbCtls = SHORT1FROMMR( WinSendMsg( hwnd, WM_QUERYFRAMECTLCOUNT,
  321.                                                      MPVOID, MPVOID ));
  322.  
  323.             for ( n = 0; n < cbCtls; n++ )
  324.             {
  325.                pswp[ n ].fl &= ~( SWP_SHOW );
  326.                pswp[ n ].cx =  0;
  327.                pswp[ n ].cy =  0;
  328.             }
  329.  
  330.             return ( MRFROMSHORT( cbCtls ));
  331.          }
  332.  
  333.       case WM_BUTTON1DBLCLK:
  334.       case WM_BUTTON2DBLCLK:
  335.          {
  336.             WinSendMsg( hwnd, WM_COMMAND, MPFROMSHORT( IDM_MAILREADER ),
  337.                         MPFROM2SHORT( CMDSRC_OTHER, TRUE ));
  338.          }
  339.          return ( MRTRUE );
  340.  
  341.  
  342.       case WM_BUTTON1MOTIONSTART:
  343.       case WM_BUTTON2MOTIONSTART:
  344.          {
  345.             WinSendMsg( hwnd, WM_TRACKFRAME, MPFROMSHORT( TF_MOVE | TF_SETPOINTERPOS ),
  346.                         MPVOID );
  347.          }
  348.          return ( MRTRUE );
  349.  
  350.       case WM_CONTEXTMENU :
  351.          {
  352.             if ( hmenu != NULLHANDLE )
  353.             {
  354.                POINTL ptl;
  355.  
  356.                WinQueryPointerPos( HWND_DESKTOP, &ptl );
  357.  
  358.                WinPopupMenu( HWND_DESKTOP, hwnd, hmenu, ptl.x, ptl.y, IDM_MAILREADER,
  359.                              PU_POSITIONONITEM | PU_HCONSTRAIN | PU_VCONSTRAIN | PU_NONE |
  360.                              PU_SELECTITEM | PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_MOUSEBUTTON2 );
  361.             }
  362.          }
  363.          return ( MRTRUE );
  364.  
  365.       case WM_COMMAND :
  366.          {
  367.             switch ( SHORT1FROMMP( mp1 ))
  368.             {
  369.                case IDM_PROPERTIES:
  370.                   {
  371.                      Configure( hwnd, pcfg );
  372.                   }
  373.                   break;
  374.  
  375.                case PB_REFRESH:
  376.                   {
  377.                      if (( cbOldMsgs > 0 ) && *( pcfg->szProgram ) && WinIsMenuItemEnabled( hmenu, IDM_MAILREADER ))
  378.                      {
  379.                         if ( LaunchMailreader( hwnd, pcfg ) == NULLHANDLE )
  380.                         {
  381.                            WinAlarm( HWND_DESKTOP, WA_ERROR );
  382.                            WinMessageBox( HWND_DESKTOP, hwnd, "Unable to load reader", "ERROR",
  383.                                           0, MB_ENTER | MB_MOVEABLE | MB_ERROR );
  384.                         }
  385.                         else
  386.                         {
  387.                            WinEnableMenuItem( hmenu, IDM_MAILREADER, FALSE );
  388.                            break;
  389.                         }
  390.                      }
  391.                   }
  392.                   /* fall through to refresh... */
  393.  
  394.                case IDM_REFRESH:
  395.                   {
  396.                      WinSetWindowText( hwndStatus, "--" );
  397.  
  398.                      bForced = TRUE;
  399.  
  400.                      PollNow( pcfg );
  401.                   }
  402.                   break;
  403.  
  404.                case IDM_MAILREADER:
  405.                   {
  406.                      if ( LaunchMailreader( hwnd, pcfg ) == NULLHANDLE )
  407.                      {
  408.                         WinAlarm( HWND_DESKTOP, WA_ERROR );
  409.                         WinMessageBox( HWND_DESKTOP, hwnd, "Unable to load reader", "ERROR",
  410.                                        0, MB_ENTER | MB_MOVEABLE | MB_ERROR );
  411.                      }
  412.                      else
  413.                      {
  414.                         WinEnableMenuItem( hmenu, IDM_MAILREADER, FALSE );
  415.                      }
  416.                   }
  417.                   break;
  418.             }
  419.          }
  420.          return ( MRZERO );
  421.  
  422.       case WM_USER:
  423.          {
  424.             LONG cbMsgs;
  425.  
  426.             cbMsgs = LONGFROMMP( mp1 );
  427.             if (( cbMsgs != cbOldMsgs ) || bForced )
  428.             {
  429.                CHAR      szMsgs[ 32 ];
  430.                ULONG     ulColor;
  431.                HPOINTER  hicon;
  432.  
  433.                bForced   = FALSE;
  434.                
  435.                if ( cbMsgs < 0 )
  436.                {
  437.                   cbMsgs = -( cbMsgs );
  438.  
  439.                   strcpy( szMsgs, "PMLPP - " );
  440.  
  441.                   if ( cbMsgs >= MAXERRORMSGS )
  442.                   {
  443.                      strcat( szMsgs, "????" );
  444.                   }
  445.                   else
  446.                   {
  447.                      strcat( szMsgs, ErrorMsgs[ cbMsgs - 1 ] );
  448.                   }
  449.  
  450.                   ulColor = CLR_RED;
  451.                   hicon = hiconMain;
  452.                }
  453.                else if ( cbMsgs == 0 )
  454.                {
  455.                   sprintf( szMsgs, "PMLPP - 0" );
  456.                   ulColor = CLR_PALEGRAY;
  457.                   hicon = hiconMain;
  458.                }
  459.                else
  460.                {
  461.                   sprintf( szMsgs, "PMLPP - %lu", cbMsgs );
  462.                   ulColor = CLR_GREEN;
  463.                   hicon = hiconMail;
  464.  
  465.                   if (( cbOldMsgs <= 0 ) && ( pcfg->bSound ))
  466.                   {
  467.                      WinAlarm( HWND_DESKTOP, WA_NOTE );
  468.                   }
  469.                }
  470.  
  471.                cbOldMsgs = cbMsgs;
  472.  
  473.                WinSetPresParam( hwndButton, PP_BACKGROUNDCOLORINDEX, sizeof( ulColor ),
  474.                                 &ulColor );
  475.  
  476.                WinSetWindowText( hwndStatus, szMsgs + 8 );
  477.  
  478.                if ( cbMsgs >= 0 )
  479.                {
  480.                   strcat( szMsgs, " Msgs" );
  481.                }
  482.  
  483.                WinSetWindowText( hwnd, szMsgs );
  484.  
  485.                WinSendMsg( hwnd, WM_SETICON, MPFROMLONG( hicon ), MPVOID );
  486.  
  487.                SetButtonIcon( hwndButton, hicon );
  488.             }
  489.          }
  490.          return ( MRZERO );
  491.  
  492.       case WM_DESTROY:
  493.          {
  494.             SWP swp;
  495.  
  496.             StopPolling( pcfg );
  497.  
  498.             if ( hwndHelp != NULLHANDLE )
  499.             {
  500.                WinAssociateHelpInstance( NULLHANDLE, hwnd );
  501.                WinDestroyHelpInstance( hwndHelp );
  502.             }
  503.  
  504.             WinQueryWindowPos( hwnd, &swp );
  505.  
  506.             if (( swp.x != pcfg->ptl.x ) || ( swp.y != pcfg->ptl.y ))
  507.             {
  508.                pcfg->ptl.x = swp.x;
  509.                pcfg->ptl.y = swp.y;
  510.  
  511.                SaveProfile( hwnd, pcfg );
  512.             }
  513.          }
  514.          return ( MRZERO );
  515.  
  516.       case WM_APPTERMINATENOTIFY:
  517.          {
  518.             WinEnableMenuItem( hmenu, IDM_MAILREADER, TRUE );
  519.             PollNow( pcfg );
  520.          }
  521.          return ( MRZERO );
  522.  
  523.       case WM_HELP:
  524.          {
  525.             switch ( SHORT1FROMMP( mp1 ))
  526.             {
  527.                case IDM_HELPINDEX:
  528.                   {
  529.                      WinSendMsg( hwndHelp, HM_HELP_INDEX, MPVOID, MPVOID );
  530.                   }
  531.                   break;
  532.  
  533.                case 0: /* F1 */
  534.                case PB_HELP:
  535.                case IDM_GENERALHELP:
  536.                   {
  537.                      WinSendMsg( hwndHelp, HM_HELP_CONTENTS, MPVOID, MPVOID );
  538.                   }
  539.                   break;
  540.  
  541.                case IDM_USINGHELP:
  542.                   {
  543.                      WinSendMsg( hwndHelp, HM_DISPLAY_HELP, MPVOID, MPVOID );
  544.                   }
  545.                   break;
  546.  
  547.                case IDM_ABOUTPMLPP:
  548.                   {
  549.                      HWND hwndAbout = WinLoadDlg( HWND_DESKTOP, hwnd, WinDefDlgProc,
  550.                                                   NULLHANDLE, DLG_ABOUT, 0 );
  551.                      if ( hwndAbout != NULLHANDLE )
  552.                      {
  553.                         CenterWindow( hwndAbout );
  554.  
  555.                         WinProcessDlg( hwndAbout );
  556.  
  557.                         WinDestroyWindow( hwndAbout );
  558.                      }
  559.                   }
  560.                   break;
  561.             }
  562.          }
  563.          return ( MRZERO );
  564.    }
  565.  
  566.    return ( WinDefDlgProc( hwnd, msg, mp1, mp2 ));
  567. };
  568.  
  569. int
  570. main( void )
  571. /**********/
  572. {
  573.    HAB hab = WinInitialize( 0 );
  574.    if ( hab != NULLHANDLE )
  575.    {
  576.       HMQ hmq = WinCreateMsgQueue( hab, 0 );
  577.       if ( hmq != NULLHANDLE )
  578.       {
  579.          HMTX hmtx;
  580.  
  581.          if ( DosCreateMutexSem( "\\SEM32\\PMLPP", &hmtx, DC_SEM_SHARED, TRUE ) == NO_ERROR )
  582.          {
  583.             CONFIG cfg = { 0 };
  584.             HWND   hwnd = WinLoadDlg( HWND_DESKTOP, HWND_DESKTOP, PMLPPDlgProc,
  585.                                       NULLHANDLE, DLG_PMLPP, &cfg );
  586.             if ( hwnd != NULLHANDLE )
  587.             {
  588.                WinProcessDlg( hwnd );
  589.                WinDestroyWindow( hwnd );
  590.             }
  591.  
  592.             DosCloseMutexSem( hmtx );
  593.          }
  594.          else
  595.          {
  596.             WinAlarm( HWND_DESKTOP, WA_ERROR );
  597.  
  598.             hmtx = NULLHANDLE;
  599.  
  600.             if ( DosOpenMutexSem( "\\SEM32\\PMLPP", &hmtx ) == NO_ERROR )
  601.             {
  602.                PID     pid = 0;
  603.                TID     tid = 0;
  604.                ULONG   ulJunk;
  605.  
  606.                if ( DosQueryMutexSem( hmtx, &pid, &tid, &ulJunk ) == NO_ERROR )
  607.                {
  608.                   HSWITCH hswitch;
  609.  
  610.                   hswitch = WinQuerySwitchHandle( NULLHANDLE, pid );
  611.                   if ( hswitch != NULLHANDLE )
  612.                   {
  613.                      WinSwitchToProgram( hswitch );
  614.                   }
  615.                }
  616.  
  617.                DosCloseMutexSem( hmtx );
  618.             }
  619.          }
  620.  
  621.          WinDestroyMsgQueue( hmq );
  622.       }
  623.  
  624.       WinTerminate( hab );
  625.    }
  626.  
  627.    return ( 0 );
  628. }
  629.